﻿using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace imvs
{
    public static class EditorUtils
    {
        private static Editor Editor =>
            Application.DocumentManager.MdiActiveDocument.Editor;

        // 打印列表内容到AutoCAD命令行
        public static void Print(object obj)
        {
            if (obj == null) return;

            if (obj is IEnumerable<object>)
            {
                IEnumerable<object> myList = (IEnumerable<object>)obj;
                var sb = new StringBuilder();
                foreach (var item in myList)
                {
                    sb.Append(item?.ToString() ?? "");
                }
                Editor.WriteMessage(sb.ToString() + "\n");
            }
            else if (obj is ArrayList)
            {
                IEnumerable<object> myList = ((ArrayList)obj).Cast<object>();
                var sb = new StringBuilder();
                foreach (var item in myList)
                {
                    sb.Append(item?.ToString() ?? "");
                }
                Editor.WriteMessage(sb.ToString() + "\n");
            }
            else
            {
                Editor.WriteMessage(obj.ToString() + "\n");
            }

        }

        // 选择单个实体
        public static ObjectId SelectEntity(string message)
        {
            PromptEntityOptions opt = new PromptEntityOptions(message);
            PromptEntityResult res = Editor.GetEntity(opt);

            return res.Status == PromptStatus.OK ? res.ObjectId : ObjectId.Null;
        }
    
        public static Tuple<bool, double> GetDouble(string prompt, Nullable<double> defaultValue = null)
        {
            var opts = new PromptDoubleOptions($"\n{prompt}: ");
            if (defaultValue.HasValue)
            {
                opts.DefaultValue = defaultValue.Value;
                opts.UseDefaultValue = true;  // 启用默认值功能
                opts.AppendKeywordsToMessage = true; // 在提示中显示默认值
                //opts.AllowNone = true;
            }

            PromptDoubleResult res = Editor.GetDouble(opts);
            if (res.Status == PromptStatus.OK)
            {
                return Tuple.Create(true, res.Value);
            }
            else if (res.Status == PromptStatus.None)
            {
                return Tuple.Create(true, defaultValue.Value);
            }
            else
            {
                return Tuple.Create(false, 0.0);
            }
        }

        public static Tuple<bool, Point3d> GetPoint(string prompt, Nullable<Point3d> basePt = null)
        {
            var opts = new PromptPointOptions($"\n{prompt}: ");
            if (basePt.HasValue)
            {
                opts.UseBasePoint = true;
                opts.BasePoint = basePt.Value;
            }
            opts.AllowNone = true;

            PromptPointResult res = Editor.GetPoint(opts);
            if (res.Status == PromptStatus.OK)
            {
                return Tuple.Create(true, res.Value);
            }
            else
            {
                return Tuple.Create(false, Point3d.Origin);
            }
        }

        public static string GetFileForSave(string defaultPath)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;

            // 创建文件对话框选项
            PromptSaveFileOptions options = new PromptSaveFileOptions("保存数据到文件");
            if (!string.IsNullOrEmpty(defaultPath))
            {
                options.InitialFileName = defaultPath;
            }
            options.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*";

            // 显示文件对话框
            PromptFileNameResult result = ed.GetFileNameForSave(options);
            if (result.Status == PromptStatus.OK)
            {
                return result.StringResult;
            }
            else
            {
                ed.WriteMessage("\n操作已取消，未选择文件。");
                return null;
            }
        }

        public static string GetFileForOpen(string defaultPath)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;

            // 设置默认文件名
            string defaultFile = string.IsNullOrEmpty(defaultPath) ?
                "mvs_data.txt" : defaultPath;

            // 创建文件对话框选项
            PromptOpenFileOptions options = new PromptOpenFileOptions("选择数据文件");
            if (!string.IsNullOrEmpty(defaultPath))
            {
                options.InitialFileName = defaultPath;
            }
            options.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*";

            // 显示文件对话框
            PromptFileNameResult result = ed.GetFileNameForOpen(options);
            if (result.Status == PromptStatus.OK)
            {
                return result.StringResult;
            }
            else
            {
                ed.WriteMessage("\n操作已取消，未选择文件。");
                return null;
            }
        }

        /// <summary>
        /// 获取选择集
        /// </summary>
        /// <param name="selectStr">选择方式</param>
        /// <param name="point3dCollection">选择点集合</param>
        /// <param name="typedValue">过滤参数</param>
        /// <returns></returns>
        public static SelectionSet SelectSsGet(string selectStr, Point3dCollection point3dCollection, TypedValue[] typedValue)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;

            // 将过滤条件赋值给SelectionFilter对象
            SelectionFilter selfilter = null;
            if (typedValue != null)
            {
                selfilter = new SelectionFilter(typedValue);
            }
            // 请求在图形区域选择对象
            PromptSelectionResult psr;
            if (selectStr == "GetSelection")  // 提示用户从图形文件中选取对象
            {
                psr = ed.GetSelection(selfilter);
            }
            else if (selectStr == "SelectAll") //选择当前空间内所有未锁定及未冻结的对象
            {
                psr = ed.SelectAll(selfilter);
            }
            else if (selectStr == "SelectCrossingPolygon") //选择由给定点定义的多边形内的所有对象以及与多边形相交的对象。多边形可以是任意形状，但不能与自己交叉或接触。
            {
                psr = ed.SelectCrossingPolygon(point3dCollection, selfilter);
            }
            // 选择与选择围栏相交的所有对象。围栏选择与多边形选择类似，所不同的是围栏不是封闭的， 围栏同样不能与自己相交
            else if (selectStr == "SelectFence")
            {
                psr = ed.SelectFence(point3dCollection, selfilter);
            }
            // 选择完全框入由点定义的多边形内的对象。多边形可以是任意形状，但不能与自己交叉或接触
            else if (selectStr == "SelectWindowPolygon")
            {
                psr = ed.SelectWindowPolygon(point3dCollection, selfilter);
            }
            else if (selectStr == "SelectCrossingWindow")  //选择由两个点定义的窗口内的对象以及与窗口相交的对象
            {
                Point3d point1 = point3dCollection[0];
                Point3d point2 = point3dCollection[1];
                psr = ed.SelectCrossingWindow(point1, point2, selfilter);
            }
            else if (selectStr == "SelectWindow") // 选择完全框入由两个点定义的矩形内的所有对象。
            {
                Point3d point1 = point3dCollection[0];
                Point3d point2 = point3dCollection[1];
                psr = ed.SelectCrossingWindow(point1, point2, selfilter);
            }
            else
            {
                return null;
            }

            // 如果提示状态OK，表示对象已选
            if (psr.Status == PromptStatus.OK)
            {
                SelectionSet sSet = psr.Value;
                ed.WriteMessage("Number of objects selected: " + sSet.Count.ToString() + "\n");// 打印选择对象数量
                return sSet;
            }
            else
            {
                // 打印选择对象数量
                ed.WriteMessage("Number of objects selected 0 \n");
                return null;
            }
        }

		public static bool AskToContinue()
		{
			Document doc = Application.DocumentManager.MdiActiveDocument;
			Editor ed = doc.Editor;

			// 定义关键字选项
			PromptKeywordOptions pko = new PromptKeywordOptions("\n是否继续？ [是(Y)/否(N)]");
			pko.Keywords.Add("Y", "是(Y)");
			pko.Keywords.Add("N", "否(N)");
			pko.AllowNone = false; // 必须选择

			// 获取用户输入
			PromptResult result = ed.GetKeywords(pko);

			return result.StringResult == "Y"; // 返回 true（继续）或 false（取消）
		}

	}

}
